package security.filters;

import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import tk.mybatis.mapper.util.Assert;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AuthenticationData {
    @Getter
    private long id;
    @Getter
    private String token;
    @Getter
    private long sid;

    public AuthenticationData(long id, String token, long sid) {
        this.id = id;
        this.sid = sid;
        this.token = token != null ? token : "";
    }

    public String toBase64() {
        byte[] tbs = token.getBytes(StandardCharsets.UTF_8);
        ByteBuffer buffer = ByteBuffer.allocate(tbs.length + 16);
        buffer.putLong(id);
        buffer.putLong(sid);
        if (tbs.length > 0) {
            buffer.put(tbs);
        }
        return Base64.getEncoder().encodeToString(buffer.array());
    }

    public static AuthenticationData fromBase64(String base64) {
        if (StringUtils.isBlank(base64)) {
            return null;
        }
        byte[] bytes;
        try {
            bytes = Base64.getDecoder().decode(base64);
        } catch (Exception exception) {
            return null;
        }
        String token = "";
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        long id = buffer.getLong();
        long sid = buffer.getLong();
        if (buffer.remaining() > 0) {
            byte[] tbs = new byte[buffer.remaining()];
            buffer.get(tbs);
            token = new String(tbs, StandardCharsets.UTF_8);
        }
        return new AuthenticationData(id, token, sid);
    }

    public static void main(String[] args) {
        String base64 = new AuthenticationData(1765446464, "tokenGT", 245646464).toBase64();
        System.out.println(base64);
        AuthenticationData authenticationData = AuthenticationData.fromBase64(base64);
        assert authenticationData != null;
        System.out.printf("%d, %s ,%d \r\n", authenticationData.getId(), authenticationData.getToken(), authenticationData.getSid());
        Assert.isTrue(authenticationData.getId() == 1765446464
                && authenticationData.getToken().equals("tokenGT")
                && authenticationData.getSid() == 245646464, "AuthenticationData serialization fail");
        //
        base64 = new AuthenticationData(1765446464, null, 245646464).toBase64();
        System.out.println(base64);
        authenticationData = AuthenticationData.fromBase64(base64);
        assert authenticationData != null;
        System.out.printf("%d, %s ,%d \r\n", authenticationData.getId(), authenticationData.getToken(), authenticationData.getSid());
        Assert.isTrue(authenticationData.getId() == 1765446464
                && "".equals(authenticationData.getToken())
                && authenticationData.getSid() == 245646464, "AuthenticationData serialization fail");
    }


}
